﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;

namespace YJKArch.NumberRoom
{
	public class PickNumberControler
	{
		public PickNumberControler(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
		}

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public void Create()
		{
			Autodesk.Revit.DB.Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			Autodesk.Revit.DB.View activeView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
			PickNumberForm pickNumberForm = new PickNumberForm();
			pickNumberForm.Show(CmdPickNumberRoom._hWndRevit);
			int wMsg = 7;
			PickNumberControler.SendMessage(CmdPickNumberRoom._hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			Transaction transaction = null;
			XYZ pt = null;
			try
			{
				transaction = new Transaction(document);
				transaction.Start("create room tag");
				while (this.SelelctPosision(ref pt))
				{
					if (pickNumberForm.RoomNumberValidating())
					{
						Room room = null;
						if (this.GetRoomByPoint(pt, pickNumberForm.CreateRoom, ref room))
						{
							string text = pickNumberForm.RoomTagFirstName + pickNumberForm.RoomTagNumber.ToString() + pickNumberForm.RoomTagSecondName;
							if (Common.GetRoomName(room).CompareTo(text) != 0)
							{
								if (Common.HasSameNameRoomTag(document, activeView.Id, text))
								{
									if (pickNumberForm.PromptSameName)
									{
										MessageBox.Show("存在同名房间标记。", "盈建科提示");
										continue;
									}
									this.ChangeTagNameWithSameNameRoomTag(room.Id, pickNumberForm.RoomTagFirstName, pickNumberForm.RoomTagNumber, pickNumberForm.RoomTagSecondName, pickNumberForm.IsContinuous);
								}
								Common.CreateRoomTag(document, activeView, room, pt, text);
								Common.UpdateModel(this.m_Revit.Application.ActiveUIDocument, false);
								PickNumberControler.SendMessage(pickNumberForm.Handle, 1281, IntPtr.Zero, IntPtr.Zero);
							}
						}
					}
				}
				transaction.Commit();
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				pickNumberForm.Close();
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				return;
			}
			pickNumberForm.Close();
		}

		protected bool SelelctPosision(ref XYZ pt)
		{
			try
			{
				pt = this.m_Revit.Application.ActiveUIDocument.Selection.PickPoint("选取房间标记位置");
			}
			catch (Exception)
			{
				return false;
			}
			return true;
		}

		private bool GetRoomByPoint(XYZ pt, bool createRoom, ref Room selectRoom)
		{
			double num = AssistFunc.mmToFeet(10.0);
			num *= num;
			List<ElementId> list = new List<ElementId>();
			Autodesk.Revit.DB.Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			Level genLevel = this.m_Revit.Application.ActiveUIDocument.ActiveView.GenLevel;
			foreach (object obj in document.get_PlanTopology(genLevel).Circuits)
			{
				PlanCircuit planCircuit = (PlanCircuit)obj;
				if (!planCircuit.IsRoomLocated && !this.LessThan(planCircuit.Area, num) && createRoom)
				{
					Room room2 = document.Create.NewRoom(null, planCircuit);
					list.Add(room2.Id);
				}
			}
			bool result = false;
            using (List<Room>.Enumerator enumerator2 = YJKArch.NumberRoom.Common.GetRooms(document, this.m_Revit.Application.ActiveUIDocument.ActiveView.Id).GetEnumerator())
			{
				while (enumerator2.MoveNext())
				{
					Room room = enumerator2.Current;
					if (room.IsPointInRoom(pt))
					{
						int num2 = list.FindIndex((ElementId id) => id.Compare(room.Id) == 0);
						if (num2 < 0)
						{
							selectRoom = room;
						}
						else if (createRoom)
						{
							list.RemoveAt(num2);
							selectRoom = room;
						}
						result = true;
						break;
					}
				}
			}
			foreach (ElementId elementId in list)
			{
				document.Delete(elementId);
			}
			return result;
		}

		private bool LessThan(double val1, double val2)
		{
			return val1 - val2 < -1E-09;
		}

		private void ChangeTagNameWithSameNameRoomTag(ElementId selectRoomId, string roomTagFirstName, int roomTagNumber, string roomTagSecondName, bool isContinuous)
		{
			Autodesk.Revit.DB.Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			ElementId id = this.m_Revit.Application.ActiveUIDocument.ActiveView.Id;
            IEnumerable<Room> enumerable = from elem in new FilteredElementCollector(document, id).WherePasses(new Autodesk.Revit.DB.Architecture.RoomFilter()).ToElements()
			let theRoom = elem as Room
			where theRoom != null
			select theRoom;
			if (enumerable == null)
			{
				return;
			}
			List<PickNumberControler.RoomNumberInfo> list = new List<PickNumberControler.RoomNumberInfo>();
			foreach (Room room in enumerable)
			{
				if (room.Id.Compare(selectRoomId) != 0)
				{
					string roomName = Common.GetRoomName(room);
					if (roomName.IndexOf(roomTagFirstName) == 0)
					{
						int num = roomName.Length;
						if (roomTagSecondName.CompareTo("") != 0)
						{
							num = roomName.IndexOf(roomTagSecondName);
						}
						if (num - roomTagFirstName.Length >= 1 && roomName.Length - roomTagSecondName.Length == num)
						{
							string str = roomName.Substring(roomTagFirstName.Length, num - roomTagFirstName.Length);
							int num2 = 0;
							if (Common.ConvertToInt(str, ref num2) && num2 >= roomTagNumber)
							{
								list.Add(new PickNumberControler.RoomNumberInfo
								{
									number = num2,
									room = room
								});
							}
						}
					}
				}
			}
			if (list.Count < 1)
			{
				return;
			}
			list.Sort((PickNumberControler.RoomNumberInfo left, PickNumberControler.RoomNumberInfo right) => left.number.CompareTo(right.number));
			int num3 = 1;
			if (!isContinuous)
			{
				num3 = 2;
			}
			List<PickNumberControler.RoomNumberInfo> list2 = new List<PickNumberControler.RoomNumberInfo>();
			list2.Add(list[0]);
			for (int i = 1; i < list.Count; i++)
			{
				int number = list[i - 1].number;
				if (list[i].number - number > num3)
				{
					break;
				}
				list2.Add(list[i]);
			}
			list2.Reverse();
			foreach (PickNumberControler.RoomNumberInfo roomNumberInfo in list2)
			{
				Room room2 = roomNumberInfo.room;
				string strName = roomTagFirstName + (roomNumberInfo.number + num3).ToString() + roomTagSecondName;
				Common.SetRoomName(room2, strName);
			}
		}

		private ExternalCommandData m_Revit;

		public const int USER = 1280;

		public const int WM_MYMESSAGE = 1281;

		private const double _epsDouble = 1E-09;

		private struct RoomNumberInfo
		{
			public int number;

			public Room room;
		}
	}
}
